package com.gemini.main.counter;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * com.gemini.main.counter.IncompleteCounter
 *
 * 为了循序渐进，我们把“计数器需要有回收机制”这条要求去掉，这样我们可以很容易地利用上AtomicInteger这个类
 *
 * @author zhanghailin
 */
public class IncompleteCounter implements Counter {

    private ConcurrentHashMap<String, Adder> map = new ConcurrentHashMap<>();

    @Override
    public void save(Saver saver) {
        map.forEach((key, value) -> {//利用了AtomicInteger的原子特性，可以线程安全地取出所有计数，并置0(因为还会继续使用)
            saver.save(key, value.like.getAndSet(0), value.comment.getAndSet(0));
        });
        //因为不回收，所以不用考虑Adder被回收丢弃后，仍被其它线程使用的情况(因为没有锁，所以这种情况是可能发生的)
    }

    @Override
    public void add(String key, int like, int comment) {
        Adder adder = map.computeIfAbsent(key, k -> new Adder());
        adder.like.addAndGet(like);//利用AtomicInteger的原子特性，保证了线程安全
        adder.comment.addAndGet(comment);
    }

    static class Adder {
        AtomicInteger like = new AtomicInteger();
        AtomicInteger comment = new AtomicInteger();
    }
}
